diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigation.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigation.java index b71ac2aba83..affcd4df412 100644 --- a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigation.java +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigation.java @@ -39,7 +39,8 @@ import timber.log.Timber; import static com.mapbox.services.android.navigation.v5.navigation.NavigationConstants.BANNER_INSTRUCTION_MILESTONE_ID; -import static com.mapbox.services.android.navigation.v5.navigation.NavigationConstants.NON_NULL_APPLICATION_CONTEXT_REQUIRED; +import static com.mapbox.services.android.navigation.v5.navigation.NavigationConstants + .NON_NULL_APPLICATION_CONTEXT_REQUIRED; import static com.mapbox.services.android.navigation.v5.navigation.NavigationConstants.VOICE_INSTRUCTION_MILESTONE_ID; /** @@ -67,6 +68,7 @@ public class MapboxNavigation implements ServiceConnection { private final String accessToken; private Context applicationContext; private boolean isBound; + private RouteRefresher routeRefresher; static { NavigationLibraryLoader.load(); @@ -845,6 +847,11 @@ LocationEngineRequest retrieveLocationEngineRequest() { return locationEngineRequest; } + @Nullable + RouteRefresher retrieveRouteRefresher() { + return routeRefresher; + } + private void initializeForTest() { // Initialize event dispatcher and add internal listeners navigationEventDispatcher = new NavigationEventDispatcher(); @@ -926,6 +933,7 @@ private LocationEngineRequest obtainLocationEngineRequest() { private void startNavigationWith(@NonNull DirectionsRoute directionsRoute, DirectionsRouteType routeType) { ValidationUtils.validDirectionsRoute(directionsRoute, options.defaultMilestonesEnabled()); this.directionsRoute = directionsRoute; + routeRefresher = new RouteRefresher(this, new RouteRefresh(accessToken)); mapboxNavigator.updateRoute(directionsRoute, routeType); if (!isBound) { navigationTelemetry.startSession(directionsRoute, locationEngine); diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigationOptions.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigationOptions.java index d79085cee64..189448152b3 100644 --- a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigationOptions.java +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigationOptions.java @@ -8,6 +8,7 @@ import static com.mapbox.services.android.navigation.v5.navigation.NavigationConstants .NAVIGATION_LOCATION_ENGINE_INTERVAL_LAG; import static com.mapbox.services.android.navigation.v5.navigation.NavigationConstants.ROUNDING_INCREMENT_FIFTY; +import static com.mapbox.services.android.navigation.v5.navigation.NavigationConstants.ROUTE_REFRESH_INTERVAL; /** * Immutable and can't be changed after passing into {@link MapboxNavigation}. @@ -21,6 +22,20 @@ public abstract class MapboxNavigationOptions { public abstract boolean enableAutoIncrementLegIndex(); + /** + * This value indicates if route refresh is enabled or disabled. + * + * @return whether route refresh is enabled or not + */ + public abstract boolean enableRefreshRoute(); + + /** + * This value indicates the route refresh interval. + * + * @return route refresh interval in milliseconds + */ + public abstract long refreshIntervalInMilliseconds(); + public abstract boolean isFromNavigationUi(); public abstract boolean isDebugLoggingEnabled(); @@ -47,6 +62,22 @@ public abstract static class Builder { public abstract Builder enableAutoIncrementLegIndex(boolean enableAutoIncrementLegIndex); + /** + * This enables / disables refresh route. If not specified, it's enabled by default. + * + * @param enableRefreshRoute whether or not to enable route refresh + * @return this builder for chaining options together + */ + public abstract Builder enableRefreshRoute(boolean enableRefreshRoute); + + /** + * This sets the route refresh interval. If not specified, the interval is 5 minutes by default. + * + * @param intervalInMilliseconds for route refresh + * @return this builder for chaining options together + */ + public abstract Builder refreshIntervalInMilliseconds(long intervalInMilliseconds); + public abstract Builder isFromNavigationUi(boolean isFromNavigationUi); public abstract Builder isDebugLoggingEnabled(boolean debugLoggingEnabled); @@ -66,6 +97,8 @@ public static Builder builder() { return new AutoValue_MapboxNavigationOptions.Builder() .enableFasterRouteDetection(false) .enableAutoIncrementLegIndex(true) + .enableRefreshRoute(true) + .refreshIntervalInMilliseconds(ROUTE_REFRESH_INTERVAL) .defaultMilestonesEnabled(true) .isFromNavigationUi(false) .isDebugLoggingEnabled(false) diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationConstants.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationConstants.java index b47dba9449d..f3b488638c8 100644 --- a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationConstants.java +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationConstants.java @@ -123,6 +123,8 @@ private NavigationConstants() { */ static final int NAVIGATION_LOCATION_ENGINE_INTERVAL_LAG = 1500; + static final long ROUTE_REFRESH_INTERVAL = 5 * 60 * 1000L; + /** * Defines the minimum zoom level of the displayed map. */ diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationRoute.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationRoute.java index 1e91bcd6594..76bc309992b 100644 --- a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationRoute.java +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationRoute.java @@ -680,7 +680,8 @@ public NavigationRoute build() { .voiceInstructions(true) .bannerInstructions(true) .roundaboutExits(true) - .eventListener(eventListener); + .eventListener(eventListener) + .enableRefresh(true); return new NavigationRoute(directionsBuilder.build()); } diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/RouteProcessorRunnable.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/RouteProcessorRunnable.java index 2a14ff0caeb..4a77bbfeaa3 100644 --- a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/RouteProcessorRunnable.java +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/RouteProcessorRunnable.java @@ -55,11 +55,17 @@ private void process() { MapboxNavigationOptions options = navigation.options(); DirectionsRoute route = navigation.getRoute(); - NavigationStatus status = mapboxNavigator.retrieveStatus(new Date(), + Date date = new Date(); + NavigationStatus status = mapboxNavigator.retrieveStatus(date, options.navigationLocationEngineIntervalLagInMilliseconds()); status = checkForNewLegIndex(mapboxNavigator, route, status, options.enableAutoIncrementLegIndex()); RouteProgress routeProgress = routeProcessor.buildNewRouteProgress(mapboxNavigator, status, route); + RouteRefresher routeRefresher = navigation.retrieveRouteRefresher(); + if (routeRefresher != null && routeRefresher.check(date)) { + routeRefresher.refresh(routeProgress); + } + NavigationEngineFactory engineFactory = navigation.retrieveEngineFactory(); final boolean userOffRoute = isUserOffRoute(options, status, rawLocation, routeProgress, engineFactory); final Location snappedLocation = findSnappedLocation(status, rawLocation, routeProgress, engineFactory); diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/RouteRefresh.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/RouteRefresh.java index f28f25d73ad..09541b8d76b 100644 --- a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/RouteRefresh.java +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/RouteRefresh.java @@ -4,40 +4,77 @@ import com.mapbox.api.directionsrefresh.v1.MapboxDirectionsRefresh; import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress; +import timber.log.Timber; + /** * This class allows the developer to interact with the Directions Refresh API, receiving updated * annotations for a route previously requested with the enableRefresh flag. */ public final class RouteRefresh { - private final RefreshCallback refreshCallback; + private RefreshCallback refreshCallback; private final String accessToken; /** * Creates a {@link RouteRefresh} object which calls the {@link RefreshCallback} with updated * routes. * - * @param accessToken mapbox access token + * @param accessToken mapbox access token * @param refreshCallback to call with updated routes + * @deprecated use {@link RouteRefresh(String)} instead */ + @Deprecated public RouteRefresh(String accessToken, RefreshCallback refreshCallback) { this.accessToken = accessToken; this.refreshCallback = refreshCallback; } + /** + * Creates a {@link RouteRefresh} object. + * + * @param accessToken mapbox access token + */ + public RouteRefresh(String accessToken) { + this.accessToken = accessToken; + } + /** * Refreshes the {@link DirectionsRoute} included in the {@link RouteProgress} and returns it * to the callback that was originally passed in. The client will then have to update their * {@link DirectionsRoute} with the {@link com.mapbox.api.directions.v5.models.LegAnnotation}s * returned in this response. The leg annotations start at the current leg index of the * {@link RouteProgress} + *

+ * Note that if {@link RefreshCallback} is not passed in {@link RouteRefresh(String, RefreshCallback)} this call + * will be ignored. + *

* * @param routeProgress to refresh via the route and current leg index + * @deprecated use {@link RouteRefresh#refresh(RouteProgress, RefreshCallback)} instead */ + @Deprecated public void refresh(RouteProgress routeProgress) { - refresh(routeProgress.directionsRoute(), routeProgress.legIndex()); + if (refreshCallback == null) { + Timber.e("RefreshCallback cannot be null."); + return; + } + refresh(routeProgress.directionsRoute(), routeProgress.legIndex(), refreshCallback); + } + + /** + * Refreshes the {@link DirectionsRoute} included in the {@link RouteProgress} and returns it + * to the callback that was originally passed in. The client will then have to update their + * {@link DirectionsRoute} with the {@link com.mapbox.api.directions.v5.models.LegAnnotation}s + * returned in this response. The leg annotations start at the current leg index of the + * {@link RouteProgress} + * + * @param routeProgress to refresh via the route and current leg index + * @param refreshCallback to call with updated routes + */ + public void refresh(RouteProgress routeProgress, RefreshCallback refreshCallback) { + refresh(routeProgress.directionsRoute(), routeProgress.legIndex(), refreshCallback); } - private void refresh(final DirectionsRoute directionsRoute, final int legIndex) { + private void refresh(final DirectionsRoute directionsRoute, final int legIndex, RefreshCallback refreshCallback) { MapboxDirectionsRefresh.builder() .requestId(directionsRoute.routeOptions().requestUuid()) .routeIndex(Integer.valueOf(directionsRoute.routeIndex())) diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/RouteRefreshCallback.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/RouteRefreshCallback.java index a95d3ee13bb..b6c6e2d6c8c 100644 --- a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/RouteRefreshCallback.java +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/RouteRefreshCallback.java @@ -13,8 +13,7 @@ class RouteRefreshCallback implements Callback { private final int legIndex; private final RefreshCallback refreshCallback; - RouteRefreshCallback(DirectionsRoute directionsRoute, - int legIndex, RefreshCallback refreshCallback) { + RouteRefreshCallback(DirectionsRoute directionsRoute, int legIndex, RefreshCallback refreshCallback) { this(new RouteAnnotationUpdater(), directionsRoute, legIndex, refreshCallback); } @@ -31,13 +30,12 @@ public void onResponse(Call call, Response call, Throwable throwable) { - refreshCallback.onError(new RefreshError("There was a network error.")); + refreshCallback.onError(new RefreshError(throwable.getMessage())); } } diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/RouteRefresher.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/RouteRefresher.java new file mode 100644 index 00000000000..539ce0c1ff3 --- /dev/null +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/RouteRefresher.java @@ -0,0 +1,43 @@ +package com.mapbox.services.android.navigation.v5.navigation; + +import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress; + +import java.util.Date; + +class RouteRefresher { + private final MapboxNavigation mapboxNavigation; + private final RouteRefresh routeRefresh; + private final long refreshIntervalInMilliseconds; + private Date lastRefreshedDate; + private boolean isChecking; + private boolean isRefreshRouteEnabled; + + RouteRefresher(MapboxNavigation mapboxNavigation, RouteRefresh routeRefresh) { + this.mapboxNavigation = mapboxNavigation; + this.routeRefresh = routeRefresh; + this.refreshIntervalInMilliseconds = mapboxNavigation.options().refreshIntervalInMilliseconds(); + this.lastRefreshedDate = new Date(); + this.isRefreshRouteEnabled = mapboxNavigation.options().enableRefreshRoute(); + } + + boolean check(Date currentDate) { + if (isChecking || !isRefreshRouteEnabled) { + return false; + } + long millisSinceLastRefresh = currentDate.getTime() - lastRefreshedDate.getTime(); + return millisSinceLastRefresh > refreshIntervalInMilliseconds; + } + + void refresh(RouteProgress routeProgress) { + updateIsChecking(true); + routeRefresh.refresh(routeProgress, new RouteRefresherCallback(mapboxNavigation, this)); + } + + void updateLastRefresh(Date date) { + lastRefreshedDate = date; + } + + void updateIsChecking(boolean isChecking) { + this.isChecking = isChecking; + } +} diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/RouteRefresherCallback.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/RouteRefresherCallback.java new file mode 100644 index 00000000000..713cccd1753 --- /dev/null +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/RouteRefresherCallback.java @@ -0,0 +1,30 @@ +package com.mapbox.services.android.navigation.v5.navigation; + +import com.mapbox.api.directions.v5.models.DirectionsRoute; + +import java.util.Date; + +import timber.log.Timber; + +class RouteRefresherCallback implements RefreshCallback { + private final MapboxNavigation mapboxNavigation; + private final RouteRefresher routeRefresher; + + RouteRefresherCallback(MapboxNavigation mapboxNavigation, RouteRefresher routeRefresher) { + this.mapboxNavigation = mapboxNavigation; + this.routeRefresher = routeRefresher; + } + + @Override + public void onRefresh(DirectionsRoute directionsRoute) { + mapboxNavigation.startNavigation(directionsRoute, DirectionsRouteType.FRESH_ROUTE); + routeRefresher.updateLastRefresh(new Date()); + routeRefresher.updateIsChecking(false); + } + + @Override + public void onError(RefreshError error) { + Timber.w(error.getMessage()); + routeRefresher.updateIsChecking(false); + } +} diff --git a/libandroid-navigation/src/test/java/com/mapbox/services/android/navigation/v5/navigation/RouteRefresherCallbackTest.java b/libandroid-navigation/src/test/java/com/mapbox/services/android/navigation/v5/navigation/RouteRefresherCallbackTest.java new file mode 100644 index 00000000000..114477c0039 --- /dev/null +++ b/libandroid-navigation/src/test/java/com/mapbox/services/android/navigation/v5/navigation/RouteRefresherCallbackTest.java @@ -0,0 +1,67 @@ +package com.mapbox.services.android.navigation.v5.navigation; + +import com.mapbox.api.directions.v5.models.DirectionsRoute; + +import org.junit.Test; + +import java.util.Date; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +public class RouteRefresherCallbackTest { + + @Test + public void checksStartNavigationWithRefreshedRouteIsCalledWhenOnRefresh() { + MapboxNavigation mockedMapboxNavigation = mock(MapboxNavigation.class); + RouteRefresher mockedRouteRefresher = mock(RouteRefresher.class); + RouteRefresherCallback theRouteRefresherCallback = new RouteRefresherCallback(mockedMapboxNavigation, + mockedRouteRefresher); + DirectionsRoute anyRoute = mock(DirectionsRoute.class); + + theRouteRefresherCallback.onRefresh(anyRoute); + + verify(mockedMapboxNavigation).startNavigation(eq(anyRoute), eq(DirectionsRouteType.FRESH_ROUTE)); + } + + @Test + public void checksUpdateLastRefreshDateIsCalledWhenOnRefresh() { + MapboxNavigation mockedMapboxNavigation = mock(MapboxNavigation.class); + RouteRefresher mockedRouteRefresher = mock(RouteRefresher.class); + RouteRefresherCallback theRouteRefresherCallback = new RouteRefresherCallback(mockedMapboxNavigation, + mockedRouteRefresher); + DirectionsRoute anyRoute = mock(DirectionsRoute.class); + + theRouteRefresherCallback.onRefresh(anyRoute); + + verify(mockedRouteRefresher).updateLastRefresh(any(Date.class)); + } + + @Test + public void checksUpdateIsNotCheckingAfterOnRefresh() { + MapboxNavigation mockedMapboxNavigation = mock(MapboxNavigation.class); + RouteRefresher mockedRouteRefresher = mock(RouteRefresher.class); + RouteRefresherCallback theRouteRefresherCallback = new RouteRefresherCallback(mockedMapboxNavigation, + mockedRouteRefresher); + DirectionsRoute anyRoute = mock(DirectionsRoute.class); + + theRouteRefresherCallback.onRefresh(anyRoute); + + verify(mockedRouteRefresher).updateIsChecking(eq(false)); + } + + @Test + public void checksUpdateIsNotCheckingIfOnError() { + MapboxNavigation mockedMapboxNavigation = mock(MapboxNavigation.class); + RouteRefresher mockedRouteRefresher = mock(RouteRefresher.class); + RouteRefresherCallback theRouteRefresherCallback = new RouteRefresherCallback(mockedMapboxNavigation, + mockedRouteRefresher); + RefreshError anyRefreshError = mock(RefreshError.class); + + theRouteRefresherCallback.onError(anyRefreshError); + + verify(mockedRouteRefresher).updateIsChecking(eq(false)); + } +} \ No newline at end of file diff --git a/libandroid-navigation/src/test/java/com/mapbox/services/android/navigation/v5/navigation/RouteRefresherTest.java b/libandroid-navigation/src/test/java/com/mapbox/services/android/navigation/v5/navigation/RouteRefresherTest.java new file mode 100644 index 00000000000..7f330c3e3ff --- /dev/null +++ b/libandroid-navigation/src/test/java/com/mapbox/services/android/navigation/v5/navigation/RouteRefresherTest.java @@ -0,0 +1,129 @@ +package com.mapbox.services.android.navigation.v5.navigation; + +import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress; + +import org.junit.Test; + +import java.util.Date; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class RouteRefresherTest { + + @Test + public void checksShouldRefreshIfIntervalHasPassed() { + MapboxNavigation mockedMapboxNavigation = mock(MapboxNavigation.class); + RouteRefresh mockedRouteRefresh = mock(RouteRefresh.class); + long aRefreshIntervalInMilliseconds = 1; + MapboxNavigationOptions mockedMapboxNavigationOptions = mock(MapboxNavigationOptions.class); + when(mockedMapboxNavigation.options()).thenReturn(mockedMapboxNavigationOptions); + when(mockedMapboxNavigationOptions.refreshIntervalInMilliseconds()).thenReturn(aRefreshIntervalInMilliseconds); + when(mockedMapboxNavigationOptions.enableRefreshRoute()).thenReturn(true); + RouteRefresher theRouteRefresher = new RouteRefresher(mockedMapboxNavigation, mockedRouteRefresh); + Date aDate = new Date(); + Date aDatePassedTheInterval = new Date(aDate.getTime() + aRefreshIntervalInMilliseconds + 1); + + boolean shouldRefresh = theRouteRefresher.check(aDatePassedTheInterval); + + assertTrue(shouldRefresh); + } + + @Test + public void checksShouldNotRefreshIfIntervalHasNotPassed() { + MapboxNavigation mockedMapboxNavigation = mock(MapboxNavigation.class); + RouteRefresh mockedRouteRefresh = mock(RouteRefresh.class); + long aRefreshIntervalInMilliseconds = 1; + MapboxNavigationOptions mockedMapboxNavigationOptions = mock(MapboxNavigationOptions.class); + when(mockedMapboxNavigation.options()).thenReturn(mockedMapboxNavigationOptions); + when(mockedMapboxNavigationOptions.refreshIntervalInMilliseconds()).thenReturn(aRefreshIntervalInMilliseconds); + RouteRefresher theRouteRefresher = new RouteRefresher(mockedMapboxNavigation, mockedRouteRefresh); + when(mockedMapboxNavigationOptions.enableRefreshRoute()).thenReturn(true); + Date aDate = new Date(); + Date aDatePassedTheInterval = new Date(aDate.getTime() + aRefreshIntervalInMilliseconds); + + boolean shouldRefresh = theRouteRefresher.check(aDatePassedTheInterval); + + assertFalse(shouldRefresh); + } + + @Test + public void checksShouldNotRefreshIfCurrentlyChecking() { + MapboxNavigation mockedMapboxNavigation = mock(MapboxNavigation.class); + RouteRefresh mockedRouteRefresh = mock(RouteRefresh.class); + long aRefreshIntervalInMilliseconds = 1; + MapboxNavigationOptions mockedMapboxNavigationOptions = mock(MapboxNavigationOptions.class); + when(mockedMapboxNavigation.options()).thenReturn(mockedMapboxNavigationOptions); + when(mockedMapboxNavigationOptions.refreshIntervalInMilliseconds()).thenReturn(aRefreshIntervalInMilliseconds); + when(mockedMapboxNavigationOptions.enableRefreshRoute()).thenReturn(true); + RouteRefresher theRouteRefresher = new RouteRefresher(mockedMapboxNavigation, mockedRouteRefresh); + Date aDate = new Date(); + Date aDatePassedTheInterval = new Date(aDate.getTime() + aRefreshIntervalInMilliseconds + 1); + + theRouteRefresher.updateIsChecking(true); + boolean shouldRefresh = theRouteRefresher.check(aDatePassedTheInterval); + + assertFalse(shouldRefresh); + } + + @Test + public void checksShouldNotRefreshIfRouteRefreshIsNotEnabled() { + MapboxNavigation mockedMapboxNavigation = mock(MapboxNavigation.class); + RouteRefresh mockedRouteRefresh = mock(RouteRefresh.class); + long aRefreshIntervalInMilliseconds = 1; + MapboxNavigationOptions mockedMapboxNavigationOptions = mock(MapboxNavigationOptions.class); + when(mockedMapboxNavigation.options()).thenReturn(mockedMapboxNavigationOptions); + when(mockedMapboxNavigationOptions.refreshIntervalInMilliseconds()).thenReturn(aRefreshIntervalInMilliseconds); + when(mockedMapboxNavigationOptions.enableRefreshRoute()).thenReturn(false); + RouteRefresher theRouteRefresher = new RouteRefresher(mockedMapboxNavigation, mockedRouteRefresh); + Date aDate = new Date(); + Date aDatePassedTheInterval = new Date(aDate.getTime() + aRefreshIntervalInMilliseconds + 1); + + theRouteRefresher.updateIsChecking(true); + boolean shouldRefresh = theRouteRefresher.check(aDatePassedTheInterval); + + assertFalse(shouldRefresh); + } + + @Test + public void checksUpdateIsCheckingWhenRefresh() { + MapboxNavigation mockedMapboxNavigation = mock(MapboxNavigation.class); + RouteRefresh mockedRouteRefresh = mock(RouteRefresh.class); + long aRefreshIntervalInMilliseconds = 1; + MapboxNavigationOptions mockedMapboxNavigationOptions = mock(MapboxNavigationOptions.class); + when(mockedMapboxNavigation.options()).thenReturn(mockedMapboxNavigationOptions); + when(mockedMapboxNavigationOptions.refreshIntervalInMilliseconds()).thenReturn(aRefreshIntervalInMilliseconds); + when(mockedMapboxNavigationOptions.enableRefreshRoute()).thenReturn(true); + RouteRefresher theRouteRefresher = new RouteRefresher(mockedMapboxNavigation, mockedRouteRefresh); + Date aDate = new Date(); + Date aDatePassedTheInterval = new Date(aDate.getTime() + aRefreshIntervalInMilliseconds + 2); + RouteProgress mockedRouteProgress = mock(RouteProgress.class); + + theRouteRefresher.refresh(mockedRouteProgress); + boolean shouldRefresh = theRouteRefresher.check(aDatePassedTheInterval); + + assertFalse(shouldRefresh); + } + + @Test + public void checksRouteRefreshIsCalledWhenRefresh() { + MapboxNavigation mockedMapboxNavigation = mock(MapboxNavigation.class); + RouteRefresh mockedRouteRefresh = mock(RouteRefresh.class); + long aRefreshIntervalInMilliseconds = 1; + MapboxNavigationOptions mockedMapboxNavigationOptions = mock(MapboxNavigationOptions.class); + when(mockedMapboxNavigation.options()).thenReturn(mockedMapboxNavigationOptions); + when(mockedMapboxNavigationOptions.refreshIntervalInMilliseconds()).thenReturn(aRefreshIntervalInMilliseconds); + when(mockedMapboxNavigationOptions.enableRefreshRoute()).thenReturn(true); + RouteRefresher theRouteRefresher = new RouteRefresher(mockedMapboxNavigation, mockedRouteRefresh); + RouteProgress mockedRouteProgress = mock(RouteProgress.class); + + theRouteRefresher.refresh(mockedRouteProgress); + + verify(mockedRouteRefresh).refresh(eq(mockedRouteProgress), any(RouteRefresherCallback.class)); + } +} \ No newline at end of file