Skip to content

Commit 8859bdc

Browse files
committed
Update tests and api
1 parent 2071fe8 commit 8859bdc

File tree

8 files changed

+225
-275
lines changed

8 files changed

+225
-275
lines changed

libnavigation-core/api/current.txt

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ package com.mapbox.navigation.core {
3232
method public com.mapbox.navigation.core.trip.session.TripSessionState getTripSessionState();
3333
method public Integer? getZLevel();
3434
method public boolean isDestroyed();
35+
method @com.mapbox.navigation.base.ExperimentalPreviewMapboxNavigationAPI public boolean isReplayEnabled();
3536
method public boolean isRunningForegroundService();
3637
method @com.mapbox.navigation.base.ExperimentalPreviewMapboxNavigationAPI @kotlin.jvm.Throws(exceptionClasses=IllegalArgumentException::class) public void moveRoutesFromPreviewToNavigator() throws java.lang.IllegalArgumentException;
3738
method public void navigateNextRouteLeg(com.mapbox.navigation.core.trip.session.LegIndexUpdatedCallback callback);
@@ -1021,6 +1022,53 @@ package com.mapbox.navigation.core.telemetry.events {
10211022

10221023
}
10231024

1025+
package com.mapbox.navigation.core.trip {
1026+
1027+
@com.mapbox.navigation.base.ExperimentalPreviewMapboxNavigationAPI public final class MapboxTripStarter implements com.mapbox.navigation.core.lifecycle.MapboxNavigationObserver {
1028+
method public static com.mapbox.navigation.core.trip.MapboxTripStarter create();
1029+
method public com.mapbox.navigation.core.trip.MapboxTripStarterOptions getOptions();
1030+
method public static com.mapbox.navigation.core.trip.MapboxTripStarter getRegisteredInstance();
1031+
method public void onAttached(com.mapbox.navigation.core.MapboxNavigation mapboxNavigation);
1032+
method public void onDetached(com.mapbox.navigation.core.MapboxNavigation mapboxNavigation);
1033+
method public com.mapbox.navigation.core.trip.MapboxTripStarter setOptions(com.mapbox.navigation.core.trip.MapboxTripStarterOptions options);
1034+
method public void update(kotlin.jvm.functions.Function1<? super com.mapbox.navigation.core.trip.MapboxTripStarterOptions.Builder,com.mapbox.navigation.core.trip.MapboxTripStarterOptions.Builder> function);
1035+
field public static final com.mapbox.navigation.core.trip.MapboxTripStarter.Companion Companion;
1036+
}
1037+
1038+
public static final class MapboxTripStarter.Companion {
1039+
method public com.mapbox.navigation.core.trip.MapboxTripStarter create();
1040+
method public com.mapbox.navigation.core.trip.MapboxTripStarter getRegisteredInstance();
1041+
}
1042+
1043+
public final class MapboxTripStarterExtra {
1044+
field public static final com.mapbox.navigation.core.trip.MapboxTripStarterExtra INSTANCE;
1045+
field public static final String MAPBOX_TRIP_STARTER_FOLLOW_DEVICE = "MAPBOX_TRIP_STARTER_FOLLOW_DEVICE";
1046+
field public static final String MAPBOX_TRIP_STARTER_REPLAY_ROUTE = "MAPBOX_TRIP_STARTER_REPLAY_ROUTE";
1047+
}
1048+
1049+
@StringDef({com.mapbox.navigation.core.trip.MapboxTripStarterExtra.MAPBOX_TRIP_STARTER_FOLLOW_DEVICE, com.mapbox.navigation.core.trip.MapboxTripStarterExtra.MAPBOX_TRIP_STARTER_REPLAY_ROUTE}) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public static @interface MapboxTripStarterExtra.Type {
1050+
}
1051+
1052+
@com.mapbox.navigation.base.ExperimentalPreviewMapboxNavigationAPI public final class MapboxTripStarterOptions {
1053+
method public com.mapbox.navigation.core.replay.route.ReplayRouteSessionOptions getReplayRouteSessionOptions();
1054+
method public String getTripType();
1055+
method public boolean isLocationPermissionGranted();
1056+
method public com.mapbox.navigation.core.trip.MapboxTripStarterOptions.Builder toBuilder();
1057+
property public final boolean isLocationPermissionGranted;
1058+
property public final com.mapbox.navigation.core.replay.route.ReplayRouteSessionOptions replayRouteSessionOptions;
1059+
property public final String tripType;
1060+
}
1061+
1062+
public static final class MapboxTripStarterOptions.Builder {
1063+
ctor public MapboxTripStarterOptions.Builder();
1064+
method public com.mapbox.navigation.core.trip.MapboxTripStarterOptions build();
1065+
method public com.mapbox.navigation.core.trip.MapboxTripStarterOptions.Builder isLocationPermissionGranted(boolean isLocationPermissionGranted);
1066+
method public com.mapbox.navigation.core.trip.MapboxTripStarterOptions.Builder replayRouteSessionOptions(com.mapbox.navigation.core.replay.route.ReplayRouteSessionOptions options);
1067+
method public com.mapbox.navigation.core.trip.MapboxTripStarterOptions.Builder tripType(@com.mapbox.navigation.core.trip.MapboxTripStarterExtra.Type String tripType);
1068+
}
1069+
1070+
}
1071+
10241072
package com.mapbox.navigation.core.trip.session {
10251073

10261074
public fun interface BannerInstructionsObserver {

libnavigation-core/src/main/java/com/mapbox/navigation/core/trip/MapboxTripStarter.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ import kotlinx.coroutines.launch
2929
* class a singleton. That will be done automatically if you use [getRegisteredInstance].
3030
*/
3131
@ExperimentalPreviewMapboxNavigationAPI
32-
@SuppressLint("MissingPermission")
33-
class MapboxTripStarter private constructor(): MapboxNavigationObserver {
32+
class MapboxTripStarter private constructor() : MapboxNavigationObserver {
3433

3534
private val optionsFlow = MutableStateFlow(MapboxTripStarterOptions.Builder().build())
3635
private var replayRouteTripSession: ReplayRouteSession? = null
@@ -138,6 +137,7 @@ class MapboxTripStarter private constructor(): MapboxNavigationObserver {
138137
}
139138
}
140139

140+
@SuppressLint("MissingPermission")
141141
private fun onTripSessionEnabled(mapboxNavigation: MapboxNavigation) {
142142
replayRouteTripSession?.onDetached(mapboxNavigation)
143143
replayRouteTripSession = null
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package com.mapbox.navigation.core.trip
2+
3+
import com.mapbox.android.core.permissions.PermissionsManager
4+
import com.mapbox.navigation.base.ExperimentalPreviewMapboxNavigationAPI
5+
import com.mapbox.navigation.core.MapboxNavigation
6+
import com.mapbox.navigation.core.trip.session.TripSessionState
7+
import io.mockk.every
8+
import io.mockk.mockk
9+
import io.mockk.mockkStatic
10+
import io.mockk.verify
11+
import org.junit.Assert.assertFalse
12+
import org.junit.Assert.assertTrue
13+
import org.junit.Before
14+
import org.junit.Test
15+
16+
@OptIn(ExperimentalPreviewMapboxNavigationAPI::class)
17+
class MapboxTripStarterTest {
18+
19+
private val sut = MapboxTripStarter.create()
20+
21+
@Before
22+
fun setup() {
23+
mockkStatic(PermissionsManager::class)
24+
every { PermissionsManager.areLocationPermissionsGranted(any()) } returns true
25+
}
26+
27+
@Test
28+
fun `onAttached will update location permission options`() {
29+
every { PermissionsManager.areLocationPermissionsGranted(any()) } returns true
30+
31+
val initialOptions = sut.getOptions()
32+
sut.onAttached(mockk(relaxed = true))
33+
34+
assertFalse(initialOptions.isLocationPermissionGranted)
35+
assertTrue(sut.getOptions().isLocationPermissionGranted)
36+
}
37+
38+
@Test(expected = IllegalStateException::class)
39+
fun `setOptions will crash if used before onAttached`() {
40+
val options = MapboxTripStarterOptions.Builder().isLocationPermissionGranted(true).build()
41+
sut.setOptions(options)
42+
}
43+
44+
@Test
45+
fun `onAttached will startTripSession when location permissions are granted`() {
46+
every { PermissionsManager.areLocationPermissionsGranted(any()) } returns true
47+
48+
val mapboxNavigation = mockMapboxNavigation()
49+
sut.onAttached(mapboxNavigation)
50+
51+
verify(exactly = 1) { mapboxNavigation.startTripSession() }
52+
}
53+
54+
@Test
55+
fun `onAttached will not startTripSession when location permissions are disabled`() {
56+
every { PermissionsManager.areLocationPermissionsGranted(any()) } returns false
57+
58+
val mapboxNavigation = mockMapboxNavigation()
59+
sut.onAttached(mapboxNavigation)
60+
61+
verify(exactly = 0) { mapboxNavigation.startTripSession() }
62+
}
63+
64+
@Test
65+
fun `update will startTripSession when location permissions are disabled`() {
66+
every { PermissionsManager.areLocationPermissionsGranted(any()) } returns false
67+
68+
val mapboxNavigation = mockMapboxNavigation()
69+
sut.onAttached(mapboxNavigation)
70+
every { PermissionsManager.areLocationPermissionsGranted(any()) } returns true
71+
sut.update { it.isLocationPermissionGranted(true) }
72+
73+
verify(exactly = 1) { mapboxNavigation.startTripSession() }
74+
}
75+
76+
@Test(expected = IllegalStateException::class)
77+
fun `cannot accept location permissions when they are not granted`() {
78+
every { PermissionsManager.areLocationPermissionsGranted(any()) } returns false
79+
80+
val mapboxNavigation = mockMapboxNavigation()
81+
sut.onAttached(mapboxNavigation)
82+
83+
// This throws an error because areLocationPermissionsGranted is false
84+
sut.update { it.isLocationPermissionGranted(true) }
85+
}
86+
87+
@Test
88+
fun `update can be used to enable replay route without location permissions`() {
89+
every { PermissionsManager.areLocationPermissionsGranted(any()) } returns false
90+
91+
val mapboxNavigation = mockMapboxNavigation()
92+
sut.onAttached(mapboxNavigation)
93+
sut.update { it.tripType(MapboxTripStarterExtra.MAPBOX_TRIP_STARTER_REPLAY_ROUTE) }
94+
95+
verify(exactly = 1) { mapboxNavigation.startReplayTripSession() }
96+
}
97+
98+
@Test
99+
fun `update will not restart startReplayTripSession after changes`() {
100+
every { PermissionsManager.areLocationPermissionsGranted(any()) } returns false
101+
102+
val mapboxNavigation = mockMapboxNavigation()
103+
sut.onAttached(mapboxNavigation)
104+
sut.update { it.tripType(MapboxTripStarterExtra.MAPBOX_TRIP_STARTER_REPLAY_ROUTE) }
105+
every { PermissionsManager.areLocationPermissionsGranted(any()) } returns true
106+
sut.update { it.isLocationPermissionGranted(true) }
107+
108+
verify(exactly = 1) { mapboxNavigation.startReplayTripSession() }
109+
}
110+
111+
private fun mockMapboxNavigation(): MapboxNavigation {
112+
val mapboxNavigation = mockk<MapboxNavigation>(relaxed = true)
113+
every { mapboxNavigation.getTripSessionState() } returns TripSessionState.STOPPED
114+
every { mapboxNavigation.startReplayTripSession() } answers {
115+
every { mapboxNavigation.isReplayEnabled() } returns true
116+
every { mapboxNavigation.getTripSessionState() } returns TripSessionState.STARTED
117+
}
118+
every { mapboxNavigation.startTripSession() } answers {
119+
every { mapboxNavigation.isReplayEnabled() } returns false
120+
every { mapboxNavigation.getTripSessionState() } returns TripSessionState.STARTED
121+
}
122+
every { mapboxNavigation.stopTripSession() } answers {
123+
every { mapboxNavigation.isReplayEnabled() } returns false
124+
every { mapboxNavigation.getTripSessionState() } returns TripSessionState.STOPPED
125+
}
126+
return mapboxNavigation
127+
}
128+
}

libnavui-app/src/main/java/com/mapbox/navigation/ui/app/internal/SharedApp.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ object SharedApp {
3535
DestinationStateController(store),
3636
RoutePreviewStateController(store, routeOptionsProvider),
3737
AudioGuidanceStateController(store),
38-
TripSessionStarterStateController(store),
38+
TripSessionStarterStateController(),
3939
)
4040

4141
@JvmOverloads
Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.mapbox.navigation.ui.app.internal.controller
22

33
import android.annotation.SuppressLint
4+
import com.mapbox.maps.plugin.Plugin
45
import com.mapbox.navigation.base.ExperimentalPreviewMapboxNavigationAPI
56
import com.mapbox.navigation.core.trip.MapboxTripStarter
67
import com.mapbox.navigation.core.trip.MapboxTripStarterExtra
@@ -9,17 +10,16 @@ import com.mapbox.navigation.ui.app.internal.State
910
import com.mapbox.navigation.ui.app.internal.Store
1011
import com.mapbox.navigation.ui.app.internal.tripsession.TripSessionStarterAction
1112
import com.mapbox.navigation.core.trip.MapboxTripStarterOptions
13+
import kotlinx.coroutines.flow.update
1214

1315
/**
1416
* The class is responsible to start and stop the `TripSession` for NavigationView.
15-
* @param store defines the current screen state
1617
*/
1718
@OptIn(ExperimentalPreviewMapboxNavigationAPI::class)
1819
@SuppressLint("MissingPermission")
19-
class TripSessionStarterStateController(store: Store) : StateController() {
20-
init {
21-
store.register(this)
22-
}
20+
class TripSessionStarterStateController : StateController() {
21+
22+
private val tripStarter = MapboxTripStarter.getRegisteredInstance()
2323

2424
override fun process(state: State, action: Action): State {
2525
if (action is TripSessionStarterAction) {
@@ -31,21 +31,28 @@ class TripSessionStarterStateController(store: Store) : StateController() {
3131
private fun processTripSessionAction(
3232
action: TripSessionStarterAction
3333
) {
34-
val tripStarter = MapboxTripStarter.getRegisteredInstance()
3534
when (action) {
3635
is TripSessionStarterAction.OnLocationPermission -> {
37-
tripStarter.update { it.isLocationPermissionGranted(action.granted) }
36+
updateOptions {
37+
it.isLocationPermissionGranted(action.granted)
38+
}
3839
}
3940
TripSessionStarterAction.EnableReplayTripSession -> {
40-
tripStarter.update {
41+
updateOptions {
4142
it.tripType(MapboxTripStarterExtra.MAPBOX_TRIP_STARTER_REPLAY_ROUTE)
4243
}
4344
}
4445
TripSessionStarterAction.EnableTripSession -> {
45-
tripStarter.update {
46+
updateOptions {
4647
it.tripType(MapboxTripStarterExtra.MAPBOX_TRIP_STARTER_FOLLOW_DEVICE)
4748
}
4849
}
4950
}
5051
}
52+
53+
private fun updateOptions(
54+
function: (MapboxTripStarterOptions.Builder) -> MapboxTripStarterOptions.Builder
55+
) {
56+
tripStarter.setOptions(function.invoke(tripStarter.getOptions().toBuilder()).build())
57+
}
5158
}
Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
package com.mapbox.navigation.ui.app.internal.controller
22

33
import com.mapbox.navigation.base.ExperimentalPreviewMapboxNavigationAPI
4+
import com.mapbox.navigation.core.trip.MapboxTripStarter
5+
import com.mapbox.navigation.core.trip.MapboxTripStarterExtra.MAPBOX_TRIP_STARTER_FOLLOW_DEVICE
6+
import com.mapbox.navigation.core.trip.MapboxTripStarterExtra.MAPBOX_TRIP_STARTER_REPLAY_ROUTE
7+
import com.mapbox.navigation.core.trip.MapboxTripStarterOptions
48
import com.mapbox.navigation.testing.MainCoroutineRule
59
import com.mapbox.navigation.ui.app.internal.tripsession.TripSessionStarterAction
6-
import com.mapbox.navigation.ui.app.testing.TestStore
7-
import io.mockk.spyk
10+
import io.mockk.every
11+
import io.mockk.mockk
12+
import io.mockk.mockkObject
13+
import io.mockk.unmockkAll
814
import kotlinx.coroutines.ExperimentalCoroutinesApi
15+
import org.junit.After
916
import org.junit.Assert.assertEquals
17+
import org.junit.Assert.assertTrue
1018
import org.junit.Before
1119
import org.junit.Rule
1220
import org.junit.Test
@@ -17,33 +25,44 @@ class TripSessionStarterStateControllerTest {
1725
@get:Rule
1826
var coroutineRule = MainCoroutineRule()
1927

20-
private lateinit var testStore: TestStore
28+
private lateinit var mapboxTripStarter: MapboxTripStarter
2129
private lateinit var sut: TripSessionStarterStateController
30+
private val updateSlot = mutableListOf<MapboxTripStarterOptions>()
2231

2332
@Before
2433
fun setup() {
25-
testStore = spyk(TestStore())
26-
sut = TripSessionStarterStateController(testStore)
34+
mapboxTripStarter = mockk(relaxed = true)
35+
every { mapboxTripStarter.getOptions() } returns MapboxTripStarterOptions.Builder().build()
36+
every { mapboxTripStarter.setOptions(capture(updateSlot)) } returns mapboxTripStarter
37+
38+
mockkObject(MapboxTripStarter.Companion)
39+
every { MapboxTripStarter.getRegisteredInstance() } returns mapboxTripStarter
40+
sut = TripSessionStarterStateController()
41+
}
42+
43+
@After
44+
fun teardown() {
45+
unmockkAll()
2746
}
2847

2948
@Test
3049
fun `on OnLocationPermission action should update TripSessionStarterState`() {
31-
testStore.dispatch(TripSessionStarterAction.OnLocationPermission(true))
50+
sut.process(mockk(), TripSessionStarterAction.OnLocationPermission(true))
3251

33-
assertEquals(true, testStore.state.value.tripSession.isLocationPermissionGranted)
52+
assertTrue(updateSlot[0].isLocationPermissionGranted)
3453
}
3554

3655
@Test
3756
fun `on EnableReplayTripSession action should update TripSessionStarterState`() {
38-
testStore.dispatch(TripSessionStarterAction.EnableReplayTripSession)
57+
sut.process(mockk(), TripSessionStarterAction.EnableReplayTripSession)
3958

40-
assertEquals(true, testStore.state.value.tripSession.isReplayRouteEnabled)
59+
assertEquals(MAPBOX_TRIP_STARTER_REPLAY_ROUTE, updateSlot[0].tripType)
4160
}
4261

4362
@Test
4463
fun `on EnableTripSession action should update TripSessionStarterState`() {
45-
testStore.dispatch(TripSessionStarterAction.EnableTripSession)
64+
sut.process(mockk(), TripSessionStarterAction.EnableTripSession)
4665

47-
assertEquals(false, testStore.state.value.tripSession.isReplayRouteEnabled)
66+
assertEquals(MAPBOX_TRIP_STARTER_FOLLOW_DEVICE, updateSlot[0].tripType)
4867
}
4968
}

libnavui-dropin/src/test/java/com/mapbox/navigation/dropin/NavigationViewTest.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import com.mapbox.navigation.dropin.navigationview.NavigationViewListener
2525
import com.mapbox.navigation.dropin.permission.LocationPermissionComponent
2626
import com.mapbox.navigation.dropin.roadname.RoadNameCoordinator
2727
import com.mapbox.navigation.dropin.speedlimit.SpeedLimitCoordinator
28-
import com.mapbox.navigation.dropin.tripsession.TripSessionComponent
2928
import com.mapbox.navigation.testing.LoggingFrontendTestRule
3029
import com.mapbox.navigation.ui.app.internal.SharedApp
3130
import io.mockk.CapturingSlot
@@ -110,7 +109,6 @@ class NavigationViewTest {
110109

111110
verifyRegisteredObserver(AnalyticsComponent::class)
112111
verifyRegisteredObserver(LocationPermissionComponent::class)
113-
verifyRegisteredObserver(TripSessionComponent::class)
114112
verifyRegisteredObserver(MapLayoutCoordinator::class)
115113
verifyRegisteredObserver(BackPressedComponent::class)
116114
verifyRegisteredObserver(ScalebarPlaceholderCoordinator::class)

0 commit comments

Comments
 (0)